package com.easylinkin.linkappapi.security.config;

import java.util.Date;
import java.util.Objects;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;

import com.easylinkin.bases.redis.util.RedisUtil;
import com.easylinkin.linkappapi.security.entity.LinkappUser;
import com.easylinkin.linkappapi.security.entity.LinkappUserLoginInfo;
import com.easylinkin.linkappapi.security.service.LinkappUserLoginInfoService;
import com.easylinkin.linkappapi.security.service.LinkappUserService;
import com.easylinkin.sm.constant.LogConstant.Module;
import com.easylinkin.sm.entity.Log;
import com.easylinkin.sm.service.DepartmentService;
import com.easylinkin.sm.service.LogService;

import site.morn.boot.web.Responses;
import site.morn.rest.RestBuilders;
import site.morn.rest.RestMessage;
import site.morn.support.fastjson.JsonUtils;

/**
 * 认证失败处理者
 *
 * @author timely-rain
 * @since 1.2.0, 2019/8/29
 */
@Component
public class LinkappMiniAppAuthenticationFailureHandler implements AuthenticationFailureHandler {

  @Autowired
  private LinkappUserLoginInfoService userLoginInfoService;

  @Autowired
  private LinkappUserService userService;

  @Autowired
  private LogService logService;

  @Autowired
  private DepartmentService departmentService;
  
  @Autowired
  private RedisUtil redisUtil;

  @Override
  public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
      AuthenticationException exception) {
	  LinkappUser user = null;
	String sessionKey = request.getParameter("sessionKey");
	
	Object obj = redisUtil.get(sessionKey + "_miniapplogin");
	if(obj!=null) {
		user = (LinkappUser) obj;
		request.setAttribute("username", user.getUsername());
	}
	Log log = new Log();
	log.setModuleId(Long.parseLong(Module.LOGIN));
	log.setIp(request.getRemoteAddr());
	log.setContent("用户登录");
	log.setStatus(true);
	log.setDisplay(true);
	logService.add(log);

    RestMessage message = RestBuilders.failureBuilder().code("login.failure")
        .message(exception.getMessage()).build();

    if (Objects.nonNull(user)) {
      saveLog(request, user, JsonUtils.toString(message));
      saveLoginInfo(user);
    }
    Responses.standard(response).respond(message);
  }

  /**
   * 记录登录日志
   *
   * @param request 请求
   * @param user 用户
   * @param responseMessage 响应消息
   */
  private void saveLog(HttpServletRequest request, LinkappUser user, String responseMessage) {
    Log log = new Log();
    log.setModuleId(Long.parseLong(Module.LOGIN));
    log.setIp(request.getRemoteAddr());
    log.setContent("用户登录");
    log.setStatus(false);
    log.setDisplay(true);
    log.setResponseInformation(responseMessage);
    logService.add(log);
  }

  /**
   * 记录登录次数
   *
   * @param user 用户
   */
  private void saveLoginInfo(LinkappUser user) {
	  LinkappUserLoginInfo userLoginInfo = userLoginInfoService.get(user.getId());

    if (Objects.nonNull(userLoginInfo)) {
      userLoginInfoService.addErrorCount(user.getId());
    } else {
      //第一次登陆错误
      userLoginInfo = new LinkappUserLoginInfo();
      userLoginInfo.setUserId(user.getId());
      userLoginInfo.setErrorTime(new Date());
      userLoginInfo.setErrorCount(1);
      userLoginInfoService.add(userLoginInfo);
    }
  }
}
